package notes.java.concurrent;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

/**
 * SimpleDateFormat是线程不安全的
 * 如何用它来线程安全操作？
 */
public class T6_TestSimpleDateFormat {

	// 现在要模拟一个并发程序，有5000个请求，并发量是200

	// 请求数
	private static int clientReqNum = 5000;
	// 并发数
	private static int threadSize = 200;
	
	private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>(){
		@Override
		protected DateFormat initialValue() {
			return new SimpleDateFormat("yyyy-MM-dd");
		};
	};

	// 格式化时间
	private static void format() {
		try {
			threadLocal.get().parse("2019-10-11");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) throws Exception {
		// 创建一个线程池
		ExecutorService excutorService = Executors.newCachedThreadPool();

		// 定义一个5000大小的计数器
		CountDownLatch countDownLatch = new CountDownLatch(clientReqNum);
		// 定义一个并发200的信号量
		Semaphore semaphore = new Semaphore(threadSize);

		// 启5000个线程
		for (int i = 0; i < clientReqNum; i++) {
			excutorService.execute(() -> {
				try {
					semaphore.acquire(); // 是否在200个并发量内，是就可以执行，不是就抛弃
					format(); // 调用执行方法
					semaphore.release();// 释放
					countDownLatch.countDown(); // 每运行一个线程后减1
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			});
		}

		// 等待所有线程运行完
		countDownLatch.await();
		// 关闭线程池
		excutorService.shutdown();
	}
}
